package com.kmt.plaza.sevice.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.kmt.plaza.dao.ProductCommentsMapper;
import com.kmt.plaza.dao.UserDao;
import com.kmt.plaza.entity.ProductComments;
import com.kmt.plaza.entity.User;
import com.kmt.plaza.sevice.UserService;
import com.kmt.plaza.utils.MD5Utils;
import com.kmt.plaza.utils.PageHelper;
import com.kmt.plaza.vo.ResStatus;
import com.kmt.plaza.vo.ResultVO;
import com.kmt.plaza.vo.UserListVO;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.swagger.annotations.Scope;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.lang.String;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
@Scope(name = "", description = "singleton")
public class UserServiceImpl implements UserService {
    @Autowired
    private UserDao userDao;
    @Autowired
    private ProductCommentsMapper productCommentsMapper;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    private ObjectMapper objectMapper = new ObjectMapper();
    private Logger logger = LoggerFactory.getLogger(ProductServiceImpl.class);
    /**
     * 用户注册
     * @param userName
     * @param passWord
     * @return
     */
    @Transactional
    public ResultVO userResgit(String userName, String passWord) {
        logger.info("用户注册开始......");
        synchronized (this) {
            //1.根据⽤户查询，这个⽤户是否已经被注册
            User user  = userDao.queryByName(userName);
            //2.如果没有被注册则进⾏保存操作
            if (user == null) {
                String md5Pwd = MD5Utils.md5(passWord);
                user = new User();
                user.setUserName(userName);
                user.setPassWord(md5Pwd);
                user.setUserImg("img/default.png");
                user.setUserRegtime(new Date());
                user.setUserModtime(new Date());
                int i = userDao.insertUser(user);
                if (i > 0) {
                    return new ResultVO(ResStatus.OK, "注册成功！", null);
                } else {
                    return new ResultVO(ResStatus.NO, "注册失败！", null);
                }
            } else {
                return new ResultVO(ResStatus.NO, "⽤户名已经被注册！", null);
            }
        }
    }
    /**
     * 用户登陆验证
     * @param userName
     * @param passWord
     * @return
     */
    @Override
    public ResultVO checkLogin(String userName, String passWord) {
        logger.info("用户登陆验证开始......");
        Example example = new Example(User.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("userName",userName);
        List<User> user = userDao.selectByExample(example);
        if (user.size() == 0) {
            return new ResultVO(ResStatus.NO, "登录失败，用户名不存在", null);
        } else {
            User users = user.get(0);
            String md5Pwd = MD5Utils.md5(passWord);
            if (md5Pwd.equals(users.getPassWord())) {
                JwtBuilder builder = Jwts.builder();
                HashMap<String,Object> map = new HashMap<>();
                String token = builder.setSubject(userName)
                        //设置token的生成时间
                        .setIssuedAt(new Date())
                        //设置用户的id为token的id
                        .setId(users.getUserId() + "")
                        .setClaims(map)
                        //设置token的过期时间 系统的当前时间+过期时间
                        .setExpiration(new Date(System.currentTimeMillis() + 24 * 60 * 1000))
                        //设置加密方式和加密密码
                        .signWith(SignatureAlgorithm.HS256, "kmtwangwei")
                        .compact();
                //当用户登录成功后已token为key将用户信息存到redis
                try {
                    String usersInfo = objectMapper.writeValueAsString(user.get(0));
                    stringRedisTemplate.boundValueOps(token).set(usersInfo,30, TimeUnit.MINUTES);
                } catch (JsonProcessingException e) {
                    e.printStackTrace();
                }
                return new ResultVO(ResStatus.OK, token, user);
            } else {
                return new ResultVO(ResStatus.NO, "登录失败，密码错误", null);
            }
        }
    }

    /**
     * 用户信息展示
     * @param userId
     * @return
     */
    @Override
    public ResultVO userInfoList(int userId) {
        logger.info("用户信息展示开始......");
        Example example = new Example(User.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("userId",userId);
        List<User> users = userDao.selectByExample(example);
        if(users.size()>0){
            return new ResultVO(ResStatus.OK,"success",users);
        }else {
            return new ResultVO(ResStatus.NO,"fail",null);
        }
    }

    /**
     * 用户上传头像
     * @param userId
     * @param avatar_url
     */
    @Override
    public void updateAvatar(Long userId, String avatar_url) {

    }
    /**
     * 用户修改个人信息
     * @param user
     * @return
     */
    @Override
    public int updateUserInfo(User user) {
        logger.info("用户修改个人信息开始......");
        return userDao.updateUserInfo(user);
    }
    /**
     * 管理员按关键字查找用户
     * @param userName
     * @return
     */
    @Override
    public ResultVO queryKey(String userName) {
        logger.info("管理员按关键字查找用户开始......");
        userName = "%"+userName+"%";
        List<UserListVO> list = userDao.queryKey(userName);
        if(list.size()>0){
            return new ResultVO(ResStatus.OK,"已查到用户列表",list);
        }else{
            return new ResultVO(ResStatus.NO,"未查到用户列表",null);
        }

    }
    /**
     * 管理员查询全部的用户信息的分页优化
     * @param pageNum
     * @param limit
     * @return
     */
    @Override
    public ResultVO findAll(int pageNum, int limit) {
        logger.info("管理员查询全部的用户信息开始......");
        //1、查询总记录数
        Example example = new Example(User.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("");
        int count = userDao.selectCountByExample(example);
        //2、计算总页数
        int pageCount = count%limit == 0?count/limit : (count/limit)+1;

        //查询当前页的数据
        int start = (pageNum-1)*limit;
        List<User> list = userDao.findAll(start,limit);
        ResultVO resultVO = new ResultVO(ResStatus.OK, "success", new PageHelper<User>(count, pageCount, list));
        return resultVO;
    }
    /**
     * 管理员删除用户
     * @param userId
     * @return
     */
    @Override
    public int deleteUserchanger(Integer userId) {
        logger.info("管理员删除用户开始......");
            int count= userDao.deleteUser(userId);
        return userId;
    }

    /**
     * 根据用户id查询用户所有商品评论
     * @param userId
     * @return
     */
    @Override
    public ResultVO selectAllByUserId(String userId,int pageNum, int limit) {
        logger.info("根据用户id查询用户所有商品评论开始......");
        Example example = new Example(ProductComments.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("userId",userId);
        List<ProductComments> productComments = productCommentsMapper.selectByExample(example);
        int count = productCommentsMapper.selectCountByExample(example);
        //2、计算总页数
        int pageCount = count%limit == 0?count/limit : (count/limit)+1;
        //查询当前页的数据
        int start = (pageNum-1)*limit;
        ResultVO resultVO = new ResultVO(ResStatus.OK, "success", new PageHelper<ProductComments>(count, pageCount, productComments));
        return resultVO;
    }

    @Override
    public ResultVO deleteProductComment(int commId) {
        logger.info("删除商品品论开始......");
        Example example = new Example(ProductComments.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("commId",commId);
        int i = productCommentsMapper.deleteByExample(example);
        if(i>0){
            return new ResultVO(ResStatus.OK,"success",i);
        }else {
            return new ResultVO(ResStatus.NO,"fail",null);
        }
    }
}
